package com.csust.automaticteach.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.csust.automaticteach.app.teacher.PrepareLessonApp;
import com.csust.automaticteach.bizmq.AppMessageProducer;
import com.csust.automaticteach.constant.OrderConstant;
import com.csust.automaticteach.exception.BusinessException;
import com.csust.automaticteach.exception.ErrorCode;
import com.csust.automaticteach.manager.cos.FileManager;
import com.csust.automaticteach.model.dto.file.UploadFileDetail;
import com.csust.automaticteach.model.dto.generateteach.GenerateTeachFileRequest;
import com.csust.automaticteach.model.dto.generateteach.GenerateTeachQueryDTO;
import com.csust.automaticteach.model.entity.GenerateTeach;
import com.csust.automaticteach.model.entity.User;
import com.csust.automaticteach.model.vo.generateteach.GenerateTeachVO;
import com.csust.automaticteach.model.vo.generateteach.UploadReturnVO;
import com.csust.automaticteach.service.GenerateTeachService;
import com.csust.automaticteach.mapper.GenerateTeachMapper;
import com.csust.automaticteach.utils.FileReaderUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.csust.automaticteach.constant.ExceptionConstant.SYSTEM_ERROR;
import static com.csust.automaticteach.constant.FileConstant.FILE_TYPE_ERROR;
import static com.csust.automaticteach.constant.RabbitMQConstant.PREPARE_EXCHANGE_NAME;
import static com.csust.automaticteach.constant.RabbitMQConstant.PREPARE_ROUTING_KEY;
import static com.csust.automaticteach.constant.StatusConstant.*;

/**
 * @author 钰玟
 * @description 针对表【t_generate_teach(生成教学大纲)】的数据库操作Service实现
 * @createDate 2025-06-24 08:43:29
 */
@Service
@Slf4j
public class GenerateTeachServiceImpl extends ServiceImpl<GenerateTeachMapper, GenerateTeach>
        implements GenerateTeachService{
    @Resource
    private FileReaderUtil fileReaderUtil;
    @Resource
    private PrepareLessonApp prepareLessonApp;
    @Resource
    private FileManager fileManager;
    @Resource
    private AppMessageProducer appMessageProducer;

    private final String MODULE_PREFIX = "user";

    /**
     * 上传教学大纲
     * @param file file
     * @param loginUser 当前用户
     * @return
     */
    @Override
    public UploadReturnVO uploadTeachFile(MultipartFile file, User loginUser) {
        //判断文件类型
        String filename = file.getOriginalFilename();
        if (filename == null || !(filename.endsWith(".doc") || filename.endsWith(".docx") || filename.endsWith(".pdf"))) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR,FILE_TYPE_ERROR);
        }
        String fileType = null;
        if (filename != null && filename.contains(".")) {
            //防止出现 tensorflow.js  xxx .docx
            fileType = filename.substring(filename.lastIndexOf(".") + 1);
        }
        // Read file content
        List<String> content = new ArrayList<>();
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            content = fileReaderUtil.readFile(inputStream, fileType);
        } catch (Exception e) {
            log.error("Error reading file: {}", e.getMessage());
            throw new BusinessException(ErrorCode.OPERATION_ERROR,SYSTEM_ERROR);
        }
        //构造上传（至cos）文件的前缀 用户id+业务前缀
        String filePrefix = String.format("%s/%s", MODULE_PREFIX, loginUser.getId());
        UploadFileDetail uploadFileDetail = fileManager.uploadFile(file, filePrefix);

        //处理生成大纲流程
        String context = String.join("\n", content);

        GenerateTeach generateTeach = new GenerateTeach();
        generateTeach.setStatus(WAITING);//状态
        String title = filename + "的教学内容";//标题
        generateTeach.setTitle(title);
        generateTeach.setUploadContent(context);//教学大纲
        generateTeach.setUserId(loginUser.getId());//所属用户
        generateTeach.setFileUrl(uploadFileDetail.getUrl());//教学大纲文件地址
        //插入数据库
        boolean save = this.save(generateTeach);
        if(!save){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,SYSTEM_ERROR);
        }
        //设置响应
        UploadReturnVO uploadReturnVO = new UploadReturnVO();
        uploadReturnVO.setId(generateTeach.getId());
        uploadReturnVO.setFileUrl(uploadFileDetail.getUrl());
        return uploadReturnVO;

    }

    /**
     * 生成教学大纲
     * @param generateTeachFileRequest 上传的本地课程大纲
     * @param loginUser 登录用户
     * @return 生成的教学大纲vo对象
     */
    @Override
    public GenerateTeachVO generateTeachSyn(GenerateTeachFileRequest generateTeachFileRequest, User loginUser) {
        Long generateTeachId = generateTeachFileRequest.getId();
        GenerateTeach generateTeach = this.getById(generateTeachId);
        if(generateTeach == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String uploadContent = generateTeach.getUploadContent();

        //拼接prompt
        String userPrompt = concatPrompt(uploadContent);
        //生成大纲结果 即 content
        String result = prepareLessonApp.automaticPrepareLesson(userPrompt, "1");
        //封装数据
        GenerateTeach updatedGenerateTeach = new GenerateTeach();
        updatedGenerateTeach.setContent(result);
        updatedGenerateTeach.setStatus(DRAFT);
        boolean isSaved = this.saveOrUpdate(generateTeach);
        if (!isSaved) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR,SYSTEM_ERROR);
        }
        //vo对象
        GenerateTeachVO generateTeachVO = new GenerateTeachVO();
        BeanUtil.copyProperties(generateTeach, generateTeachVO);
        return generateTeachVO;
    }
    /**
     * 生成教学大纲  异步实现 rabbitMQ 实现
     * @param generateTeachFileRequest 上传的本地课程大纲
     * @param loginUser 登录用户
     * @return 生成的教学大纲vo对象
     */
    @Override
    public GenerateTeachVO generateTeachAsy(GenerateTeachFileRequest generateTeachFileRequest, User loginUser) {
        Long generateTeachId = generateTeachFileRequest.getId();
        GenerateTeach generateTeach = this.getById(generateTeachId);
        if(generateTeach == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //处理生成大纲流程
        //封装数据,并插入数据库，提交任务
        //主键回显
        //发送给消息队列
        appMessageProducer.sendMessage(PREPARE_EXCHANGE_NAME, PREPARE_ROUTING_KEY, String.valueOf(generateTeachId));
        //vo对象
        GenerateTeachVO generateTeachVO = new GenerateTeachVO();
        BeanUtil.copyProperties(generateTeach, generateTeachVO);
        return generateTeachVO;
    }



    @Override
    public String concatPrompt(String context) {
        return   String.format("---------------------\n" +
                "{%s}\n" +
                "---------------------\n" +
                "\n" +
                "Given the provided local course outline, automatically design the teaching content." +
                " If the course outline does not provide sufficient information to design the teaching content," +
                " inform the user that the teaching content cannot be generated.", context);
    }

    // 上面的接口很多用到异常,直接定义一个工具类
    public void handleTeachUpdateError(long generateTeachId, String execMessage) {
        GenerateTeach generateTeachResult = new GenerateTeach();
        generateTeachResult.setId(generateTeachId);
        generateTeachResult.setStatus(FAILED);
        generateTeachResult.setExecMessage(execMessage);
        boolean updateResult = this.updateById(generateTeachResult);
        if (!updateResult) {
            log.error("更新教学内容失败状态失败" + generateTeachId + "," + execMessage);
        }
    }


    @Override
    public QueryWrapper<GenerateTeach> getGenerateTeachQueryWrapper(GenerateTeachQueryDTO generateTeachQueryDTO) {
        //获取查询条件
        String title = generateTeachQueryDTO.getTitle();
        Long userId = generateTeachQueryDTO.getUserId();
        Long id = generateTeachQueryDTO.getId();
        String sortField = generateTeachQueryDTO.getSortField();
        String sortOrder = generateTeachQueryDTO.getSortOrder();
        //构造queryMapper
        QueryWrapper<GenerateTeach> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjUtil.isNotNull(id), "id", id);
        queryWrapper.eq(ObjUtil.isNotNull(userId), "userId", userId);
        queryWrapper.eq(StrUtil.isNotBlank(title), "title", title);
        queryWrapper.orderBy(StrUtil.isNotBlank(sortField), OrderConstant.ASC.equals(sortOrder), sortField);
        //返回query对象
        return queryWrapper;
    }

    @Override
    public List<GenerateTeachVO> getGenerateTeachVOList(List<GenerateTeach> records) {
        return records.stream().map(this::getGenerateTeachVO).collect(Collectors.toList());
    }

    @Override
    public GenerateTeachVO getGenerateTeachVO(GenerateTeach generateTeach) {
        GenerateTeachVO generateTeachVO = new GenerateTeachVO();
        BeanUtils.copyProperties(generateTeach, generateTeachVO);
        return generateTeachVO;
    }


}




